package cn.kin.tools;

import javax.annotation.Resource;

import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.AuthenticationException;
import org.apache.shiro.authc.AuthenticationInfo;
import org.apache.shiro.authc.AuthenticationToken;
import org.apache.shiro.authc.SimpleAuthenticationInfo;
import org.apache.shiro.authc.UsernamePasswordToken;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.session.Session;
import org.apache.shiro.subject.PrincipalCollection;
import org.springframework.beans.factory.annotation.Autowired;

import cn.kin.pojo.Staff;
import cn.kin.service.StaffService;

public class ShiroDbRealm extends AuthorizingRealm {
	@Resource
	private StaffService staffService;
	public static final String SESSION_USER_KEY = "User";

	/**
	 * 授权查询回调函数, 进行鉴权但缓存中无用户的授权信息时调用,负责在应用程序中决定用户的访问控制的方法
	 */
	protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection arg0) {
		System.out.println("ShiroDbRealm---------------------doGetAuthorizationInfo");
		Staff user = (Staff) SecurityUtils.getSubject().getSession()
				.getAttribute(ShiroDbRealm.SESSION_USER_KEY);
		SimpleAuthorizationInfo info = new SimpleAuthorizationInfo();
		if(user!=null) {
			info.addRole(user.getPosition().getValueName().trim());
		}
		return info;
	}

	/**
	 * 认证回调函数，登录信息和用户验证信息验证
	 */
	protected AuthenticationInfo doGetAuthenticationInfo(
			AuthenticationToken authcToken) throws AuthenticationException {
		System.out.println("doGetAuthenticationInfo++++++++++++++++++");
		// 把token转换成User对象
		Staff userLogin = tokenToUser((UsernamePasswordToken) authcToken);
		// 验证用户是否可以登录
		Staff ui = null;
		try {
			ui = staffService.login(userLogin.getStaffNum(),
					userLogin.getPassword());
		} catch (Exception e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}
		if (ui == null)
			return null; // 异常处理，找不到数据
		// 设置session
		System.out.println("ui:name:"+ui.getName());
		Session session = SecurityUtils.getSubject().getSession();
		session.setAttribute(ShiroDbRealm.SESSION_USER_KEY, ui);
		// 当前 Realm 的 name
		String realmName = this.getName();
		// 登陆的主要信息: 可以是一个实体类的对象, 但该实体类的对象一定是根据 token 的 username 查询得到的.
		// Object principal = ui.getUsername();
		Object principal = authcToken.getPrincipal();
		return new SimpleAuthenticationInfo(principal, userLogin.getPassword(),
				realmName);
	}
	//将token对象转换为user对象
	private Staff tokenToUser(UsernamePasswordToken authcToken) {
		Staff user = new Staff();
		user.setStaffNum(authcToken.getUsername());
		user.setPassword(String.valueOf(authcToken.getPassword()));
		return user;
	}
	// 一定要写getset方法
	public StaffService getStaffService() {
		return staffService;
	}

	public void setUserService(StaffService staffService) {
		this.staffService = staffService;
	}
}
